import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df = pd.read_csv('过滤(填充缺失值).csv', encoding='gbk')
Xcols = df.columns.tolist()[10:]
morethan03 = ['PIB', 'AV45', 'FBB', 'DIGITSCOR', 'DIGITSCOR_bl', 'MriType2', 'MOCA_bl', 'EcogPtMem_bl', 'EcogPtLang_bl', 'EcogPtVisspat_bl', 'EcogPtPlan_bl', 'EcogPtOrgan_bl', 'EcogPtDivatt_bl', 'EcogPtTotal_bl', 'EcogSPMem_bl', 'EcogSPLang_bl', 'EcogSPVisspat_bl', 'EcogSPPlan_bl', 'EcogSPOrgan_bl', 'EcogSPDivatt_bl', 'EcogSPTotal_bl', 'FDG_bl', 'PIB_bl', 'AV45_bl', 'FBB_bl']
nowNanCols = ['MOCA','EcogPtMem','EcogPtLang','EcogPtVisspat','EcogPtPlan','EcogPtOrgan','EcogPtDivatt','EcogPtTotal', 'update_stamp', 'TYPE2', 'EXAMDATE_bl', 'Years_bl', 'Month_bl', 'Month', 'M']
Xcols = list(set(Xcols) - set(morethan03) - set(nowNanCols))

def toRowDf(row):
    rowDf = row.to_frame()
    rowDf = pd.DataFrame(rowDf.values.T, columns = rowDf.index)
    return rowDf

# 按TYPE和RID两层分类
DfMap = {}
for index, row in df.iterrows():
    RIDtype = row['TYPE']
    if not RIDtype in DfMap.keys():
        DfMap[RIDtype] = {}
    DfMapI = DfMap[RIDtype]
    RID = row['RID']
    if not RID in DfMapI.keys():
        DfMapI[RID] = pd.DataFrame(columns=df.columns)
    DfMapI[RID] = pd.concat([DfMapI[RID], toRowDf(row)], ignore_index=True)

# 过滤数量小于4的
for RIDtype,d in DfMap.items():
    newD = {}
    for RID, RIDdf in d.items():
        if RIDdf.shape[0]>3:
            RIDdf['EXAMDATE'] = pd.to_datetime(RIDdf['EXAMDATE'])
            RIDdf.sort_values(by='EXAMDATE', axis=0, ascending=True, inplace=True)  # 按日期排序
            newD[RID] = RIDdf
    DfMap[RIDtype] = newD

# 特征选择（对于每一类病，选择所有样本同向变化的特征）
def getGrad(RIDdf, colName):
    lastSub = RIDdf.shape[0]-1
    delta = RIDdf.loc[lastSub,colName] - RIDdf.loc[0,colName]
    dist = RIDdf.loc[lastSub,'EXAMDATE'] - RIDdf.loc[0,'EXAMDATE']
    return delta/dist.days

def isSame(RIDdf, colName):
    firstVal = RIDdf.loc[0,colName]
    for _, row in RIDdf.iterrows():
        if row[colName]!=firstVal:
            return False
    return True

def isRatioLegal(RIDret, r):
    num = 0
    for i in RIDret.values():
        if i>0:
            num += 1
    ratio = num/len(RIDret)
    return ratio>r or ratio<(1-r)

for RIDtype,d in DfMap.items():
    table = []
    for colName in Xcols:
        if np.issubdtype(df[colName].dtype, np.number) and (not df[colName].isnull().any()):
            bSame = True
            RIDret = {}
            for RID, RIDdf in d.items():
                if bSame:
                    bSame = isSame(RIDdf, colName)  # 检查这个RID该列是否全一样
                RIDret[RID] = getGrad(RIDdf, colName)
            if (not bSame) and isRatioLegal(RIDret,0.7):
                for RID, grad in RIDret.items():
                    table.append({'feature':colName, 'grad':grad})
    pd.DataFrame(table).to_csv(RIDtype+'.csv', encoding = 'gbk')